package com.dbq.fast.common.net;


import com.dbq.fast.App;
import com.dbq.fast.common.net.mock.MockRouter;

import org.reactivestreams.Subscriber;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cache;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Created by marks on 2016/8/5.
 */
public class HttpManager {
    public static final String HOST = "http://www.shadows.rocks";//192.168.1.53:8080";//
//    public static final String HOST = "http://test.d8zone.net";
    private static final int TIMEOUT = 5;
    protected HttpService httpService;
    private volatile static HttpManager httpManager;

    protected HttpManager() {
        File cacheDirectory = new File(App.getContext()
                .getCacheDir().getAbsolutePath(), "HttpCache");
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(TIMEOUT, TimeUnit.SECONDS);
        builder.readTimeout(TIMEOUT, TimeUnit.SECONDS);
        builder.writeTimeout(TIMEOUT, TimeUnit.SECONDS);
        builder.cache(new Cache(cacheDirectory, 10 * 1024 * 1024));
        builder.retryOnConnectionFailure(true);
        builder.addInterceptor(chain ->
                MockRouter.intercept(chain)
        );

        Retrofit.Builder rBuilder = new Retrofit.Builder().client(builder.build())
                .addConverterFactory(ScalarsConverterFactory.create())   //http://blog.csdn.net/u013003052/article/details/50992436
                .addConverterFactory(GsonConverterFactory.create())      //此处顺序不能和上面对调，否则不能同时兼容普通字符串和Json格式字符串
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(getHost());
        httpService = rBuilder.build().create(HttpService.class);
    }

    /**
     * 如果有不同的请求HOST可继承此类并Override
     *
     * @return
     */
    protected String getHost() {
        return HOST;
    }

    public HttpService getHttpService() {
        return httpService;
    }

    public static HttpManager getInstance() {
        if (httpManager == null) {
            synchronized (HttpManager.class) {
                if (httpManager == null) {
                    httpManager = new HttpManager();
                }
            }
        }
        return httpManager;
    }

    /**
     * 处理http请求——常规
     *
     * @param pCall
     * @param pCallback
     */
    public void doHttpRequest(Call pCall, Callback pCallback) {
        Call call = pCall;
        call.enqueue(pCallback);
    }

    /**
     * 处理http请求——RX
     * 只关注网络正常结果的处理
     *
     * @param pObservable
     * @param pSubscriber
     */
    public void doHttpRequest(Flowable pObservable, Consumer pSubscriber) {
        try {
            Flowable observable = pObservable
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
            observable.subscribe(pSubscriber);
        } catch (Exception e) {
        }
    }

    /**
     * 处理http请求——RX
     * 网络请求详尽处理
     *
     * @param pObservable
     * @param pSubscriber
     */
    public void doHttpRequest(Flowable pObservable, Subscriber pSubscriber) {
        try {
            Flowable observable = pObservable
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
            observable.subscribe(pSubscriber);
        } catch (Exception e) {
        }
    }

    /**
     * json方式传参
     *
     * @param pBody
     * @return
     */
    public RequestBody getPostBody(String pBody) {
        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), pBody);
        return body;
    }

    /**
     * 文件上传传参
     * @param files
     * @return
     */
    public  List<MultipartBody.Part> filesToMultipartBody(List<File> files) {
        List<MultipartBody.Part> parts = new ArrayList<>(files.size());

        for (File file : files) {
            RequestBody requestBody = RequestBody.create(MediaType.parse("text/*"), file);
            MultipartBody.Part part = MultipartBody.Part.createFormData("log", file.getName(), requestBody);
            parts.add(part);
        }
        return parts;
    }

}
